﻿//+-------------------------------------------------------------------------------------------------------------------------------------------------------
//
//Description: RunOnceCommandViewModel
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using VmroleAuthor.Commands;
using VmroleAuthor.Models;

namespace VmroleAuthor.ViewModels
{
    public class RunOnceCommandViewModel : ViewModelBase, IDataErrorInfo, ICleanupParamsAndPayload
    {
        private readonly StringHolder command;
        private readonly VmRoleResourceExtensionViewModel vmRoleResourceExtensionViewModel;
        private StringParameterizableProperty runOnceCommand;

         /// <summary>
        /// Constructor
        /// </summary>
        public RunOnceCommandViewModel(StringHolder comand, VmRoleResourceExtensionViewModel vmRoleResourceExtensionViewModel)
        {
            this.command = comand;
            this.vmRoleResourceExtensionViewModel = vmRoleResourceExtensionViewModel;              
        }

        public List<string> AvailableParameters
        {
            get { return this.vmRoleResourceExtensionViewModel.ResourceExtensionParametersViewModel.AvailableParameters; }
        }

        public StringHolder Command
        {
            get { return this.command; }
        }

        public StringParameterizableProperty RunOnceCommand
        {
            get
            {
                if (this.runOnceCommand == null)
                {
                    Func<string> paramValueGetter = () => this.command.Value;
                    Action<string> paramValueSetter = delegate(string value) { this.command.Value = value; };
                    Func<string> autoParamHintGetter = () => PropertyNames.RunOnceCommand;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.String
                    };

                    this.runOnceCommand = new StringParameterizableProperty(
                        PropertyNames.RunOnceCommand,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamHintGetter,
                         ParameterType.String,
                        "Run conce command parameter",
                         this.vmRoleResourceExtensionViewModel.ResourceExtensionParametersViewModel,
                         true,
                         viewDefParamInfo
                        );
                }
                return this.runOnceCommand;
            }
        }

        public void Cleanup()
        {
            this.RunOnceCommand.Cleanup();
        }

        public static class PropertyNames
        {
            public const string RunOnceCommand = "RunOnceCommand";
        }  

        public string this[string columnName]
        {
            get { return null; }
        }

        public string Error { get; set; }        
    }

    public class RunOnceCommandsViewModel : TreeViewItemViewModel, IDataErrorInfo, IProduceValidationResults
    {
        private List<StringHolder> runOnceCommands;
        private readonly VmRoleResourceExtensionViewModel vmRoleResourceExtensionViewModel;
        private readonly ObservableCollection<RunOnceCommandViewModel> runOnceCommandViewModels;
        
        public static class PropertyNames
        {
            public const string RunOnceCommandViewModels = "RunOnceCommandViewModels";
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public RunOnceCommandsViewModel(List<StringHolder> runOnceCommands, TreeViewItemViewModel parentItemViewModel, VmRoleResourceExtensionViewModel vmRoleResourceExtensionViewModel)
            : base(parentItemViewModel, true)
        {
            this.runOnceCommands = runOnceCommands;
            this.vmRoleResourceExtensionViewModel = vmRoleResourceExtensionViewModel;  
            if (this.runOnceCommands == null)
            {
                this.runOnceCommands = new List<StringHolder>();
            }
            this.runOnceCommandViewModels = new ObservableCollection<RunOnceCommandViewModel>();
            foreach (StringHolder runOnceCommand in this.runOnceCommands)
            {
                var commandViewModel = new RunOnceCommandViewModel(runOnceCommand, vmRoleResourceExtensionViewModel);
                this.runOnceCommandViewModels.Add(commandViewModel);
            }

            this.AddRunOnceCommandCommand = new RelayCommand(
            param => this.AddRunOnceCommand(),
            param => this.CanAddRunOnceCommand());

            this.DeleteRunOnceCommandCommand = new RelayCommand(
                param => this.DeleteRunOnceCommand((RunOnceCommandViewModel)param),
                param => this.CanDeleteRunOnceCommand((RunOnceCommandViewModel)param));  
 
            this.ValidationResults = new ObservableCollection<CloudServiceModelValidationResult>();
        }   

        public string Summary
        {
            get { return "Run Once Commands (" + this.runOnceCommandViewModels.Count() + ")"; }
        }

        public ObservableCollection<RunOnceCommandViewModel> RunOnceCommandViewModels
        {
            get
            {                
                return this.runOnceCommandViewModels;
            }
        }

        public ICommand AddRunOnceCommandCommand
        {
            get;
            private set;
        }

        public ICommand DeleteRunOnceCommandCommand
        {
            get;
            private set;
        }

        public bool CanAddRunOnceCommand()
        {
            return true;
        }

        public void AddRunOnceCommand()
        {
            StringHolder command = new StringHolder();
            if (this.runOnceCommands == null)
            {
                this.runOnceCommands = new List<StringHolder>();
            }
            this.runOnceCommands.Add(command);
            var runOnceCommandViewModel = new RunOnceCommandViewModel(command, this.vmRoleResourceExtensionViewModel);
            this.runOnceCommandViewModels.Add(runOnceCommandViewModel);          
        }

        public bool CanDeleteRunOnceCommand(RunOnceCommandViewModel runOnceCommandViewModel)
        {
            return true;
        }

        public void DeleteRunOnceCommand(RunOnceCommandViewModel runOnceCommandViewModel)
        {
            if (runOnceCommandViewModel != null)
            {
                runOnceCommandViewModel.Cleanup();
                if (this.runOnceCommands != null)
                {
                    this.runOnceCommands.Remove(runOnceCommandViewModel.Command);
                }
                this.runOnceCommandViewModels.Remove(runOnceCommandViewModel);
            }
        }

        public string this[string columnName]
        {
            get { return null; }
        }

        public string Error { get; set; }

        public ObservableCollection<CloudServiceModelValidationResult> ValidationResults { get; private set; }

        public void UpdateValidationResults()
        {
            this.IsExpanded = true;
            ModelValidationResultsHelper.UpdateValidationResults(this, typeof(PropertyNames));
            //Add any other cross-field validations error           
        }   
    }
}
